package frame.options.simulator;

import java.util.ArrayList;
import java.util.List;

import frame.options.simulation.Simulation;

import model.algorithms.embedding.EmbeddingAlgorithm;
import model.algorithms.embedding.NCM;
import model.algorithms.embedding.ViNE;
import model.algorithms.linksMapping.LinksMappingAlgorithm;
import model.algorithms.linksMapping.MultiCommodityFlow;
import model.algorithms.linksMapping.ShortPath;
import model.algorithms.nodesMapping.Greedy;
import model.algorithms.nodesMapping.NodesMappingAlgorithm;
import model.algorithms.rounding.Deterministic;
import model.algorithms.rounding.Randomized;
import model.algorithms.rounding.RoundingAlgorithm;
import model.algorithms.splitting.Exact;
import model.algorithms.splitting.IteratedLocalSearch;
import model.algorithms.splitting.RecursiveRandomPermutations;
import model.algorithms.splitting.SplittingAlgorithm;
import model.components.networks.factory.PhysicalNetworksFactory;
import model.components.networks.factory.VirtualNetworksFactory;
import model.components.networks.network.VirtualNetwork;
import model.components.networks.network.PhysicalNetwork;

public class Simulator
{	
	private List< PhysicalNetwork > physicalNetworks;
	public List< PhysicalNetwork > getPhysicalNetworks(){ return physicalNetworks; }
	public void setPhysicalNetworks( List< PhysicalNetwork > physicalNetworks ){ this.physicalNetworks = physicalNetworks; }
	
	private List< VirtualNetwork > virtualNetworks;
	public List< VirtualNetwork > getVirtualNetworks(){ return virtualNetworks; }
	public void setVirtualNetworks( List< VirtualNetwork > virtualNetworks ){ this.virtualNetworks = virtualNetworks; }
	
	private List< SplittingAlgorithm > splittingAlgorithms;
	public List< SplittingAlgorithm > getSplittingAlgorithms(){ return splittingAlgorithms; }
	public void setSplittingAlgorithms( List< SplittingAlgorithm > splittingAlgorithms ){ this.splittingAlgorithms = splittingAlgorithms; }
	
	private List< NodesMappingAlgorithm > nodesMappingAlgorithms;
	public List< NodesMappingAlgorithm > getNodesMappingAlgorithms(){ return nodesMappingAlgorithms; }
	public void setNodesMappingAlgorithms( List< NodesMappingAlgorithm > nodesMappingAlgorithms ){ this.nodesMappingAlgorithms = nodesMappingAlgorithms; }
	
	private List< EmbeddingAlgorithm > embeddingAlgorithms;
	public List< EmbeddingAlgorithm > getEmbeddingAlgorithms(){ return embeddingAlgorithms; }
	public void setEmbeddingAlgorithms( List< EmbeddingAlgorithm > embeddingAlgorithms ){ this.embeddingAlgorithms = embeddingAlgorithms; }
	
	private List< RoundingAlgorithm > roundingAlgorithms;
	public List< RoundingAlgorithm > getRoundingAlgorithms(){ return roundingAlgorithms; }
	public void setRoundingAlgorithms( List< RoundingAlgorithm > roundingAlgorithms ){ this.roundingAlgorithms = roundingAlgorithms; }
	
	private List< LinksMappingAlgorithm > linksMappingAlgorithms;
	public List< LinksMappingAlgorithm > getLinksMappingAlgorithms(){ return linksMappingAlgorithms; }
	public void setLinksMappingAlgorithms( List< LinksMappingAlgorithm > linksMappingAlgorithms ){ this.linksMappingAlgorithms = linksMappingAlgorithms; }
	
	private Simulation simulation;
	public Simulation getSimulation(){ return simulation; }
	public void setSimulation( Simulation simulation ){ this.simulation = simulation; }
	
	public Simulator()
	{
		this.setPhysicalNetworks( new PhysicalNetworksFactory().getPhysicalNetworks() );
		this.setVirtualNetworks( new VirtualNetworksFactory().getVirtualNetworks() );
		
		this.setSplittingAlgorithms( this.splittingAlgorithms() );
		this.setNodesMappingAlgorithms( this.nodesMappingAlgorithms() );
		this.setEmbeddingAlgorithms( this.embeddingAlgorithms() );
		this.setRoundingAlgorithms( this.roundingAlgorithms() );
		this.setLinksMappingAlgorithms( this.linksMappingAlgorithms() );
	}
	
	private List< SplittingAlgorithm > splittingAlgorithms()
	{
		List< SplittingAlgorithm > splittingAlgorithms = new ArrayList< SplittingAlgorithm >();
		splittingAlgorithms.add( new Exact( "Exact" ) );
		splittingAlgorithms.add( new IteratedLocalSearch( "Iterated Local Search" ) );
		//algorithmsNetworkSplitting.add( new IteratedLocalSearch2( "Iterated Local Search 2" ) );
		splittingAlgorithms.add( new RecursiveRandomPermutations( "Recursive Random Permutations" ) );
		
		return splittingAlgorithms; 
	}
	private List< NodesMappingAlgorithm > nodesMappingAlgorithms()
	{
		List< NodesMappingAlgorithm > nodesMappingAlgorithms = new ArrayList< NodesMappingAlgorithm >();
		nodesMappingAlgorithms.add( new Greedy( "Greedy" ) );
		
		return nodesMappingAlgorithms;
	}
	private List< EmbeddingAlgorithm > embeddingAlgorithms()
	{
		List< EmbeddingAlgorithm > embeddingAlgorithms = new ArrayList< EmbeddingAlgorithm >();
		embeddingAlgorithms.add( new NCM( "Networked Cloud Mapping" ) );
		embeddingAlgorithms.add( new ViNE( "Virtual Network Embedding" ) );
		
		return embeddingAlgorithms;
	}
	private List< RoundingAlgorithm > roundingAlgorithms()
	{
		List< RoundingAlgorithm > roundingAlgorithms = new ArrayList< RoundingAlgorithm >();
		roundingAlgorithms.add( new Deterministic( "Deterministic" ) );
		//roundingAlgorithms.add( new Deterministic2( "Deterministic Rounding 2" ) );
		roundingAlgorithms.add( new Randomized( "Randomized" ) );
		//roundingAlgorithms.add( new Randomized2( "Randomized Rounding 2" ) );
		
		return roundingAlgorithms;
	}
	private List< LinksMappingAlgorithm > linksMappingAlgorithms()
	{
		List< LinksMappingAlgorithm > linksMappingAlgorithms = new ArrayList< LinksMappingAlgorithm >();
		linksMappingAlgorithms.add( new MultiCommodityFlow( "Multi Commodity Flow" ) );
		linksMappingAlgorithms.add( new ShortPath( "Short Path" ) );
		
		return linksMappingAlgorithms;
	}
	
}
